package org.stream.transfer;


import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;

public class Transfer {


    private int targetPort;
    private String targetHost;
    private SocketChannel source;
    private SocketChannel target;
    private SelectionKey sourceKey;
    private SelectionKey targetKey;


    public Transfer(SocketChannel source) {
        this.source = source;
        targetPort = Config.getInteger("target_port", 3306);
        targetHost = Config.get("target_host", "localhost");
    }

    public void onConnect(Selector selector) {
        try {
            target = (SocketChannel) targetKey.channel();
            if (target.isConnectionPending())
                target.finishConnect();
            target.configureBlocking(false);
            target.socket().setKeepAlive(true);
            targetKey = target.register(selector, SelectionKey.OP_READ, this);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    public void register(Selector selector) {
        try {

            target = SocketChannel.open();
            target.socket().setKeepAlive(true);
            target.configureBlocking(false);
            target.connect(new InetSocketAddress(targetHost, targetPort));
            targetKey = target.register(selector, SelectionKey.OP_CONNECT, this);

            source.configureBlocking(false);
            sourceKey = source.register(selector, SelectionKey.OP_READ, this);
            source.socket().setKeepAlive(true);
            selector.wakeup();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void doRead(SelectionKey key) {
        SocketChannel r = (SocketChannel) key.channel();
        SocketChannel w = (r == source) ? target : source;
        ByteBuffer buffer = ByteBuffer.allocate(512);
        try {

            int len = r.read(buffer);
            if (len == -1) {
                close();
                return;
            }

            ByteBuffer out = ByteBuffer.allocate(512);
            byte[] bytes = buffer.array();
            System.out.println(new String(bytes, 0, len));
            out.put(bytes, 0, len);
            out.flip();
            w.write(out);


        } catch (IOException e) {
            e.printStackTrace();
            try {
                close();
            } catch (IOException ioException) {
                ioException.printStackTrace();
            }
        }


    }


    public void close() throws IOException {
        source.close();
        target.close();
        sourceKey.cancel();
        targetKey.cancel();
        System.out.println("关闭链接。");
    }


}
